package com.example.forum.controller;

import com.example.forum.common.AppResult;
import com.example.forum.common.ResultCode;
import com.example.forum.config.AppConfig;
import com.example.forum.exception.ApplicationException;
import com.example.forum.model.User;
import com.example.forum.services.IUserService;
import com.example.forum.utils.MD5Utils;
import com.example.forum.utils.StringUtils;
import com.example.forum.utils.UUIDUtils;
import com.sun.istack.internal.NotNull;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @ClassName UserController
 * @Description TODO
 * @Author H.
 * @Date 2023/5/24 8:20
 * @Version 1.0
 */
@Slf4j
@Api(tags = "用户接口")
@RestController //返回json格式的控制器
@RequestMapping("/user") //一级映射
public class UserController {

    @Resource
    IUserService userService;

    @PostMapping("/register")
    @ApiOperation("注册用户")
    public AppResult register(@ApiParam(value = "用户名") @RequestParam(value = "username") @NonNull String username,
                              @ApiParam(value = "昵称") @RequestParam(value = "nickname") @NonNull String nickname,
                              @ApiParam(value = "性别") @RequestParam(value = "gender", required = false)  Byte gender,
                              @ApiParam(value = "密码") @RequestParam(value = "password") @NonNull String password,
                              @ApiParam(value = "确认密码") @RequestParam(value = "passwordRepeat") @NonNull String passwordRepeat){

        //非空校验
        if(gender == null ||gender < 0 || gender > 2){
            //性别为保密
            gender = 2;
        }
        //密码和确认密码的校验
        if(!password.equals(passwordRepeat)){
            log.info(ResultCode.FAILED_TWO_PWD_NOT_SAME.toString());
            return AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME);
        }
        //对原始密码进进行加密
        String salt = UUIDUtils.UUID_32();
        String ciphertext = MD5Utils.md5Salt(password,salt);

        //封装用户对象
        User user = new User();
        user.setUsername(username);
        user.setNickname(nickname);
        user.setGender(gender);
        //设置密码和扰动字符
        user.setSalt(salt);
        user.setPassword(ciphertext);

        //调用业务层的代码
        userService.createNormalUser(user);
        log.info("注册成功" + user.getId());

        return AppResult.failed(ResultCode.SUCCESS);

    }

    /**
     * 用户登录
     * @param username  用户名
     * @param password  密码
     * @return
     */
    @ApiOperation("用户登录")
    @PostMapping("/login")
    public AppResult<User> login(@ApiParam(value = "用户名") @RequestParam(value = "username") @NonNull String username,
                                 @ApiParam(value = "密码") @RequestParam(value = "password") @NonNull String password,
                                    HttpServletRequest request){

        //调用service层方法登录
        User user = userService.login(username, password);
        //登录成功之后将用户信息放入session中
        HttpSession session = request.getSession(true);
        session.setAttribute(AppConfig.USER_SESSION,user);
        //返回用户信息
        return AppResult.success(user);
    }

    /**
     * 获取用户信息
     * @param request
     * @return 用户信息
     */
    @ApiOperation("获取用户信息")
    @GetMapping("/info")
    public AppResult<User> getUserInfo(HttpServletRequest request,
                                       @ApiParam("用户id") @RequestParam(value = "id" ,required = false) Long id){
       User user = null;
        //根据传入参数返回用户信息
        if(id == null) {
            //获取session
            HttpSession session = request.getSession(false);
            //获取用户信息
             user = (User) session.getAttribute(AppConfig.USER_SESSION);
        }else{
            user = userService.selectById(id);
        }
        return AppResult.success(user);

    }

    /**
     * 用户退出
     * @param request
     * @return
     */
    @ApiOperation("退出登录")
    @GetMapping("/logout")
    public AppResult logout (HttpServletRequest request) {
        // 获取用户session
        HttpSession session = request.getSession();
        if (session != null) {
            // 销毁session
            session.invalidate();
        }
        return AppResult.success();
    }

    @ApiOperation("修改用户个人信息")
    @PostMapping("/modifyInfo")
    public AppResult<User> modifyInfo (HttpServletRequest request,
                                       @ApiParam(value = "用户Id") @RequestParam(value = "id") @NonNull Long id,
                                       @ApiParam(value = "用户名") @RequestParam(value = "username", required = false) String username,
                                       @ApiParam(value = "昵称") @RequestParam(value = "nickname", required = false) String nickname,
                                       @ApiParam(value = "性别") @RequestParam(value = "gender", required = false) Byte gender,
                                       @ApiParam(value = "邮箱") @RequestParam(value = "email", required = false) String email,
                                       @ApiParam(value = "电话") @RequestParam(value = "phoneNum", required = false) String phoneNum,
                                       @ApiParam(value = "个人介绍") @RequestParam(value = "remark", required = false) String remark) {
        // 1. 获取Session中的用户信息
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        // 2. 校验传入的用户Id是否为当前登录用户
        if (user == null || user.getId() != id) {
            // 记录日志
            log.info(ResultCode.FAILED_UNAUTHORIZED.toString() + "user id = " + id);
            // 校验不通过返回未授权
            return AppResult.failed(ResultCode.FAILED_UNAUTHORIZED);
        }
        // 3. 校验性别
        if (gender != null && (gender < 0 || gender > 2)) {
            // 不符合条件设为null
            gender = null;
        }
        // 4. 校验参数
        if (StringUtils.isEmpty(username) && StringUtils.isEmpty(nickname) && gender == null
                && StringUtils.isEmpty(remark) && StringUtils.isEmpty(email) && StringUtils.isEmpty(phoneNum)) {
            // 记录日志
            log.info(ResultCode.FAILED_PARAMS_VALIDATE.toString() + "user id = " + id);
            return AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE);
        }
        // 5. 调用Service处理
        user = userService.modifyInfo(user.getId(), username, nickname, gender, email, phoneNum, remark);
        // 6. 重新设置Session中的用户信息
        session.setAttribute(AppConfig.USER_SESSION, user);
        // 7. 记录日志
        log.info("用户信息修改成功: userId = " + user.getId());
        // 8. 返回成功
        return AppResult.success(user);
    }

    @ApiOperation("修改用户密码")
    @PostMapping("/modifyPwd")
    public AppResult modifyPassword(HttpServletRequest request,
                                    @ApiParam(value = "用户Id") @RequestParam(value = "id") @NonNull Long id,
                                    @ApiParam(value = "原密码") @RequestParam(value = "oldPassword")  @NonNull String oldPassword,
                                    @ApiParam(value = "新密码") @RequestParam(value = "newPassword")  @NonNull String newPassword,
                                    @ApiParam(value = "重复新密码") @RequestParam(value = "passwordRepeat")  @NonNull String passwordRepeat){
        //获取session信息
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        //校验传入的id是否为当前登录用户Id
        if(user == null || user.getId() != id){
            // 记录日志
            log.info(ResultCode.FAILED_UNAUTHORIZED.toString() + "user id = " + id);
            // 校验不通过返回未授权
            return AppResult.failed(ResultCode.FAILED_UNAUTHORIZED);
        }
        //校验新密码与重复密码是否相同
        if(!newPassword.equals(passwordRepeat)){
            // 记录日志
            log.info(ResultCode.FAILED_TWO_PWD_NOT_SAME.toString() + "user id = " + id);
            // 返回错误信息
            return AppResult.failed(ResultCode.FAILED_TWO_PWD_NOT_SAME);
        }
        userService.modifyPassword(id,newPassword,oldPassword);
        //记录日志
        log.info("用户密码修改成功: userId = " + user.getId());
        // 返回成功
        return AppResult.success();
    }
}